<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物行为与时间维度相关性可视化</title>
    <!-- 引入 Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入 Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <!-- 引入 ECharts -->
    <script src="echarts.js"></script>

    <!-- Tailwind 配置 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#36CBCB',
                        success: '#52C41A',
                        warning: '#FAAD14',
                        danger: '#FF4D4F',
                        dark: '#1F2937',
                        light: '#F9FAFB'
                    },
                    fontFamily: {
                        inter: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>

    <style type="text/tailwindcss">
        @layer utilities { .content-auto { content-visibility: auto; } .chart-container { @apply w-full h-[350px] rounded-lg shadow-md bg-white p-4 transition-all duration-300 hover:shadow-lg; } .card-hover { @apply transition-all duration-300 hover:scale-[1.02]
        hover:shadow-xl cursor-pointer; } .active-chart { @apply scale-[1.02] shadow-xl; } .stat-card { @apply bg-white rounded-lg shadow-md p-6 transition-all duration-300 hover:shadow-lg flex flex-col items-center justify-center; } .stat-value { @apply
        text-4xl font-bold mb-2; } .stat-label { @apply text-gray-600 text-sm uppercase tracking-wider; } }
    </style>
</head>

<body class="bg-gray-50 font-inter text-dark">
    <!-- 页面头部 -->
    <header class="bg-[#fefefe] text-black shadow-lg">
        <div class="container mx-auto px-4 py-6">
            <h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold flex items-center">
                <img src="1.png" alt="Custom Image" class="mr-3 h-12 w-12">购物行为与时间维度相关性可视化
            </h1>
            <p class="text-gray-600 mt-2 max-w-3xl">根据不同时间段的购买行为决定推送策略</p>
        </div>
    </header>

    <!-- 主要内容 -->
    <main class="container mx-auto px-4 py-8">
        <!-- 统计卡片 -->
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
            <!-- 最高销售额卡片 -->
            <div class="stat-card" id="highestSalesCard">
                <div class="flex items-center justify-center mb-4">
                    <div class="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center mr-4">
                        <i class="fa fa-trophy text-primary text-xl"></i>
                    </div>
                    <div>
                        <div class="stat-value text-primary" id="highestSalesValue">21:00-24:00: 247545次</div>
                        <div class="stat-label">最高购买次数时间段</div>
                    </div>
                </div>
                <div class="w-full h-1 bg-gray-200 rounded-full overflow-hidden">
                    <div class="h-full bg-primary" style="width: 75%"></div>
                </div>
            </div>

            <!-- 新增卡片：最高日销量 -->
            <div class="stat-card" id="maxDailySalesCard">
                <div class="flex items-center justify-center mb-4">
                    <div class="w-86 h-12 rounded-full bg-warning/10 flex items-center justify-center mr-4">
                        <i class="fa fa-star text-warning text-xl"></i>
                    </div>
                    <div>
                        <div class="stat-value text-warning" id="maxDailySalesValue">2014-12-12: 56,611次</div>
                        <div class="stat-label">最高日销售量</div>
                    </div>
                </div>
                <div class="w-full h-1 bg-gray-200 rounded-full overflow-hidden">
                    <div class="h-full bg-warning" style="width: 85%"></div>
                </div>
            </div>
        </div>

        <!-- 图表网格 -->
        <div class="grid grid-cols-1 lg:grid-cols-12 gap-6">
            <!-- 左侧图表 -->
            <div class="lg:col-span-7 space-y-6">
                <!-- 柱状图卡片 - 24小时购买次数对比 移到上方 -->
                <div class="chart-card card-hover" data-chart-type="bar" data-chart-id="barChart">
                    <div class="bg-white rounded-t-lg p-4 border-b border-gray-200">
                        <h3 class="font-semibold text-lg flex items-center">
                            <i class="fa fa-bar-chart text-secondary mr-2"></i>24小时购买次数对比
                        </h3>
                    </div>
                    <div class="chart-container" id="barChart"></div>
                    <div class="bg-gray-50 rounded-b-lg p-3 text-sm text-gray-600">
                        <p>展示所有时间段的交易次数</p>
                    </div>
                </div>

                <!-- 折线图卡片 - 展示天数数据集 -->
                <div class="chart-card card-hover active-chart" data-chart-type="line" data-chart-id="daysDataChart">
                    <div class="bg-white rounded-t-lg p-4 border-b border-gray-200">
                        <h3 class="font-semibold text-lg flex items-center">
                            <i class="fa fa-line-chart text-primary mr-2"></i>每日购买次数趋势
                        </h3>
                    </div>
                    <div class="chart-container" id="daysDataChart"></div>
                    <div class="bg-gray-50 rounded-b-lg p-3 text-sm text-gray-600">
                        <p>展示2014年11月18日至12月15日的每日购买次数</p>
                    </div>
                </div>
            </div>

            <!-- 右侧图表 -->
            <div class="lg:col-span-5 space-y-6">
                <!-- 饼图卡片 -->
                <div class="chart-card card-hover" data-chart-type="pie" data-chart-id="pieChart">
                    <div class="bg-white rounded-t-lg p-4 border-b border-gray-200">
                        <h3 class="font-semibold text-lg flex items-center">
                            <i class="fa fa-pie-chart text-success mr-2"></i>24小时购买次数分布
                        </h3>
                    </div>
                    <div class="chart-container" id="pieChart"></div>
                    <div class="bg-gray-50 rounded-b-lg p-3 text-sm text-gray-600">
                        <p>展示不同时间段的购买次数占比</p>
                    </div>
                </div>

                <!-- 雷达图卡片 - 替换极坐标图 -->
                <div class="chart-card card-hover" data-chart-type="radar" data-chart-id="radarChart">
                    <div class="bg-white rounded-t-lg p-4 border-b border-gray-200">
                        <h3 class="font-semibold text-lg flex items-center">
                            <i class="fa fa-dashboard text-warning mr-2"></i>每周购买模式雷达图
                        </h3>
                    </div>
                    <div class="chart-container" id="radarChart"></div>
                    <div class="bg-gray-50 rounded-b-lg p-3 text-sm text-gray-600">
                        <p>展示每周各天的购买模式分布</p>
                    </div>
                </div>
            </div>
        </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-dark text-white mt-12 py-8">
        <div class="container mx-auto px-4">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <h2 class="text-xl font-semibold">购物行为时间分析</h2>
                    <p class="text-gray-400 mt-1">基于时间维度的购物行为可视化分析</p>
                </div>
            </div>
            <div class="border-t border-gray-800 mt-6 pt-6 text-center text-gray-500 text-sm">
                &copy; 小组成员 李泽霖 朱志斌 宋云昊 王时琛 邱俊岚 李继拓 杨一博
            </div>
        </div>
    </footer>

    <script>
        // 等待 DOM 加载完成
        document.addEventListener('DOMContentLoaded', function() {
            const charts = {
                barChart: null,
                daysDataChart: null,
                pieChart: null,
                radarChart: null
            };

            // 天数数据集 - 来自Excel文件
            const daysData = [{
                date: '11-18',
                count: 30026
            }, {
                date: '11-19',
                count: 29135
            }, {
                date: '11-20',
                count: 29209
            }, {
                date: '11-21',
                count: 26787
            }, {
                date: '11-22',
                count: 29831
            }, {
                date: '11-23',
                count: 30908
            }, {
                date: '11-24',
                count: 30850
            }, {
                date: '11-25',
                count: 29944
            }, {
                date: '11-26',
                count: 29283
            }, {
                date: '11-27',
                count: 29812
            }, {
                date: '11-28',
                count: 28553
            }, {
                date: '11-29',
                count: 30191
            }, {
                date: '11-30',
                count: 33342
            }, {
                date: '12-1',
                count: 32210
            }, {
                date: '12-2',
                count: 33002
            }, {
                date: '12-3',
                count: 33467
            }, {
                date: '12-4',
                count: 32642
            }, {
                date: '12-5',
                count: 29888
            }, {
                date: '12-6',
                count: 31658
            }, {
                date: '12-7',
                count: 32657
            }, {
                date: '12-8',
                count: 31296
            }, {
                date: '12-9',
                count: 32242
            }, {
                date: '12-10',
                count: 34039
            }, {
                date: '12-11',
                count: 39687
            }, {
                date: '12-12',
                count: 56611
            }, {
                date: '12-13',
                count: 33241
            }, {
                date: '12-14',
                count: 33134
            }, {
                date: '12-15',
                count: 32842
            }];
            // 初始化天数数据折线图
            charts.daysDataChart = initDaysDataChart(daysData);

            // 初始化柱状图
            charts.barChart = initBarChart();

            // 初始化饼图
            charts.pieChart = initPieChart();

            // 初始化雷达图（使用星期数据）
            charts.radarChart = initRadarChart(daysData);

            // 更新统计卡片数据
            updateStatCards(daysData);

            // 活跃图表 ID
            let activeChartId = 'daysDataChart';

            // 监听窗口大小变化
            window.addEventListener('resize', function() {
                if (charts[activeChartId]) {
                    charts[activeChartId].resize();
                }
            });

            // 图表卡片点击事件
            document.querySelectorAll('.chart-card').forEach(card => {
                card.addEventListener('click', function() {
                    document.querySelectorAll('.chart-card').forEach(c => c.classList.remove('active-chart'));
                    this.classList.add('active-chart');
                    activeChartId = this.dataset.chartId;
                    if (charts[activeChartId]) charts[activeChartId].resize();
                    this.scrollIntoView({
                        behavior: 'smooth',
                        block: 'center'
                    });
                });
            });
        });

        // 更新统计卡片数据
        function updateStatCards(daysData) {
            if (!daysData || daysData.length === 0) return;

            // 找到最高日销量
            let maxCount = 0;
            let maxDate = '';
            daysData.forEach(item => {
                if (item.count > maxCount) {
                    maxCount = item.count;
                    maxDate = item.date;
                }
            });

            document.getElementById('maxDailySalesValue').textContent =
                `${maxDate}: ${maxCount.toLocaleString()}次`;

            // 最高销售额时间段数据保持不变
            document.getElementById('highestSalesValue').textContent = "21:00-24:00: 247,545次";
        }

        // 初始化天数数据集折线图
        function initDaysDataChart(data) {
            const chartDom = document.getElementById('daysDataChart');
            const myChart = echarts.init(chartDom);

            // 提取日期和数量
            const dates = data.map(item => item.date);
            const counts = data.map(item => item.count);

            const option = {
                backgroundColor: 'transparent',
                color: ['#165DFF'],
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross'
                    },
                    formatter: function(params) {
                        const dateParam = params[0];
                        return `<strong>${data[dateParam.dataIndex].date}</strong><br/>` +
                            `购买次数: <b>${dateParam.value.toLocaleString()}</b> 次`;
                    }
                },
                legend: {
                    data: ['每日购买次数'],
                    top: '3%',
                    right: '3%'
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '12%',
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
                    boundaryGap: false,
                    data: dates,
                    axisLabel: {
                        rotate: 30
                    }
                },
                yAxis: {
                    type: 'value',
                    name: '购买次数',
                    axisLabel: {
                        formatter: function(value) {
                            return value.toLocaleString();
                        }
                    }
                },
                dataZoom: [{
                    type: 'slider',
                    show: true,
                    xAxisIndex: [0],
                    start: 0,
                    end: 100,
                    bottom: '3%'
                }],
                series: [{
                    name: '每日购买次数',
                    type: 'line',
                    smooth: true,
                    symbol: 'circle',
                    symbolSize: 8,
                    data: counts,
                    lineStyle: {
                        width: 3
                    },
                    areaStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                            offset: 0,
                            color: 'rgba(22, 93, 255, 0.3)'
                        }, {
                            offset: 1,
                            color: 'rgba(22, 93, 255, 0.05)'
                        }])
                    }
                }]
            };

            myChart.setOption(option);
            return myChart;
        }

        // 初始化柱状图
        function initBarChart() {
            const chartDom = document.getElementById('barChart');
            const myChart = echarts.init(chartDom);

            // 模拟24小时数据
            const hours = [];
            const counts = [];

            for (let i = 0; i < 24; i++) {
                hours.push(`${i}:00`);
                // 生成更真实的模拟数据
                if (i >= 0 && i <= 5) {
                    counts.push(Math.floor(Math.random() * 5000) + 1000);
                } else if (i >= 6 && i <= 8) {
                    counts.push(Math.floor(Math.random() * 8000) + 5000);
                } else if (i >= 9 && i <= 11) {
                    counts.push(Math.floor(Math.random() * 12000) + 10000);
                } else if (i >= 12 && i <= 13) {
                    counts.push(Math.floor(Math.random() * 15000) + 12000);
                } else if (i >= 14 && i <= 16) {
                    counts.push(Math.floor(Math.random() * 10000) + 8000);
                } else if (i >= 17 && i <= 19) {
                    counts.push(Math.floor(Math.random() * 18000) + 15000);
                } else {
                    counts.push(Math.floor(Math.random() * 25000) + 20000);
                }
            }

            const option = {
                backgroundColor: 'transparent',
                color: ['#36CBCB'],
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'shadow'
                    },
                    formatter: function(params) {
                        return `${params[0].name}<br/>购买次数: ${params[0].value.toLocaleString()}次`;
                    }
                },
                legend: {
                    data: ['购买次数'],
                    top: '3%',
                    right: '3%'
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
                    data: hours,
                    axisLabel: {
                        interval: 0,
                        rotate: 30
                    }
                },
                yAxis: {
                    type: 'value',
                    name: '次',
                    axisLabel: {
                        formatter: function(value) {
                            return value.toLocaleString();
                        }
                    }
                },
                series: [{
                    name: '购买次数',
                    type: 'bar',
                    data: counts
                }]
            };

            myChart.setOption(option);
            return myChart;
        }

        // 初始化饼图
        function initPieChart() {
            const chartDom = document.getElementById('pieChart');
            const myChart = echarts.init(chartDom);

            // 准备饼图数据
            const pieData = [{
                name: '0:00-2:59',
                value: 12450
            }, {
                name: '3:00-5:59',
                value: 8560
            }, {
                name: '6:00-8:59',
                value: 18750
            }, {
                name: '9:00-11:59',
                value: 24560
            }, {
                name: '12:00-14:59',
                value: 29870
            }, {
                name: '15:00-17:59',
                value: 22540
            }, {
                name: '18:00-20:59',
                value: 36780
            }, {
                name: '21:00-23:59',
                value: 41250
            }];

            // 计算总购买次数
            const totalValue = pieData.reduce((sum, d) => sum + d.value, 0);

            const option = {
                backgroundColor: 'transparent',
                color: [
                    '#165DFF', // 0:00-2:59
                    '#36CBCB', // 3:00-5:59
                    '#52C41A', // 6:00-8:59
                    '#FAAD14', // 9:00-11:59
                    '#FF4D4F', // 12:00-14:59
                    '#722ED1', // 15:00-17:59
                    '#F759AB', // 18:00-20:59
                    '#D3ADF7' // 21:00-23:59
                ],
                tooltip: {
                    trigger: 'item',
                    formatter: function(params) {
                        const percent = (params.value / totalValue * 100).toFixed(1);
                        return `${params.name}<br/>购买次数: ${params.value.toLocaleString()}次<br/>占比: ${percent}%`;
                    }
                },
                legend: {
                    type: 'scroll',
                    orient: 'vertical',
                    right: '5%',
                    top: '10%',
                    bottom: '10%',
                    formatter: function(name) {
                        const item = pieData.find(d => d.name === name);
                        return item ? `${name}: ${item.value.toLocaleString()}次` : name;
                    }
                },
                series: [{
                    name: '购买次数分布',
                    type: 'pie',
                    radius: ['40%', '70%'],
                    center: ['35%', '50%'],
                    avoidLabelOverlap: true,
                    itemStyle: {
                        borderRadius: 0
                    },
                    label: {
                        show: true,
                        formatter: function(params) {
                            const percent = (params.value / totalValue * 100).toFixed(1);
                            return `${params.name}\n${percent}%`;
                        }
                    },
                    emphasis: {
                        label: {
                            show: true,
                            fontSize: '14',
                            fontWeight: 'bold'
                        }
                    },
                    data: pieData,
                    startAngle: 90
                }]
            };

            myChart.setOption(option);
            return myChart;
        }

        // 初始化雷达图（使用星期数据）
        function initRadarChart(data) {
            const chartDom = document.getElementById('radarChart');
            const myChart = echarts.init(chartDom);

            // 补全日期为2014年，处理类似'11-18'的日期字符串，转为星期几
            function getWeekday(dateStr) {
                const [month, day] = dateStr.split('-').map(Number);
                const dateObj = new Date(2014, month - 1, day);
                const weekIndex = dateObj.getDay();
                const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
                return weekdays[weekIndex];
            }

            // 按星期几汇总数据
            const weekdaySummary = {};
            data.forEach(item => {
                const weekday = getWeekday(item.date);
                if (!weekdaySummary[weekday]) {
                    weekdaySummary[weekday] = 0;
                }
                weekdaySummary[weekday] += item.count;
            });

            // 星期顺序，需和雷达图 indicator 里的 name 对应
            const weekdays = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
            const counts = weekdays.map(day => weekdaySummary[day] || 0);
            const maxCount = Math.max(...counts);

            // 雷达图配置
            const option = {
                backgroundColor: 'transparent',
                tooltip: {
                    trigger: 'item',
                    formatter: function(params) {
                        return `<strong>${params.name}</strong><br/>总次数: <b>${params.value.toLocaleString()}</b>次`;
                    }
                },
                radar: {
                    indicator: weekdays.map((day, index) => {
                        return {
                            name: day,
                            max: maxCount * 1.2,
                            color: '#666'
                        };
                    }),
                    splitNumber: 5,
                    axisName: {
                        color: '#666',
                        fontSize: 12
                    },
                    splitLine: {
                        lineStyle: {
                            color: 'rgba(0, 0, 0, 0.1)'
                        }
                    },
                    splitArea: {
                        show: true,
                        areaStyle: {
                            color: ['rgba(255,255,255,0.8)', 'rgba(240, 247, 255, 0.8)']
                        }
                    },
                    axisLine: {
                        lineStyle: {
                            color: 'rgba(0, 0, 0, 0.1)'
                        }
                    }
                },
                series: [{
                    name: '购买次数',
                    type: 'radar',
                    symbol: 'circle',
                    symbolSize: 8,
                    itemStyle: {
                        color: '#165DFF'
                    },
                    lineStyle: {
                        width: 2,
                        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
                            offset: 0,
                            color: '#36CBCB'
                        }, {
                            offset: 1,
                            color: '#165DFF'
                        }])
                    },
                    areaStyle: {
                        color: new echarts.graphic.RadialGradient(0.5, 0.5, 1, [{
                            offset: 0,
                            color: 'rgba(54, 203, 203, 0.3)'
                        }, {
                            offset: 1,
                            color: 'rgba(22, 93, 255, 0.1)'
                        }])
                    },
                    data: [{
                        value: counts,
                        name: '购买次数',
                        label: {
                            show: true,
                            formatter: function(params) {
                                return (params.value / 10000).toFixed(1) + '万';
                            },
                            position: 'top',
                            color: '#333'
                        },
                        emphasis: {
                            lineStyle: {
                                width: 4
                            },
                            areaStyle: {
                                color: new echarts.graphic.RadialGradient(0.5, 0.5, 1, [{
                                    offset: 0,
                                    color: 'rgba(54, 203, 203, 0.5)'
                                }, {
                                    offset: 1,
                                    color: 'rgba(22, 93, 255, 0.2)'
                                }])
                            }
                        }
                    }]
                }]
            };
            myChart.setOption(option);
            return myChart;
        }
    </script>
</body>

</html>